﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.ComponentModel;
using System.Drawing;
using Qreed.Windows.Forms;
using Qreed.Windows;
using System.Diagnostics;

namespace GotLyrics
{
    public class ToolTipWrapper : Component
    {
        public ToolTipWrapper()
        {
            InitializeComponent();

            _sniffer.MessageReceived += new EventHandler<MessageSniffer.MessageEventArgs>(_sniffer_MessageReceived);
        }

        private Timer timerDisplayToolTip;
        private IContainer components;
        private Point _hoverPosition = Point.Empty;
        private DateTime _displayStamp = DateTime.MinValue;
        private Timer timerLeaveControl;
        private MessageSniffer _sniffer = new MessageSniffer(true);
        
        void _sniffer_MessageReceived(object sender, MessageSniffer.MessageEventArgs e)
        {
            if (e.Message.Msg == (int)WindowMessage.MOUSEHOVER)
            {
                if (!IsToolTipVisible)
                {
                    _hoverPosition = new Point((int)e.Message.LParam);
                    _hoverPosition = e.Control.PointToScreen(_hoverPosition);

                    timerDisplayToolTip.Start();
                }
            }
            else if (e.Message.Msg == (int)WindowMessage.MOUSEMOVE)
            {
                if (IsToolTipVisible && _hoverPosition != Point.Empty)
                {
                    unchecked
                    {
                        Point pt = new Point((int)e.Message.LParam);
                        pt = e.Control.PointToScreen(pt);

                        pt.X -= _hoverPosition.X;
                        pt.Y -= _hoverPosition.Y;

                        double l = Math.Sqrt(pt.X * pt.X + pt.Y * pt.Y);

                        if (l >= 25.0)
                        {
                            HideToolTip();
                        }
                    }
                }
            }
            else if (e.Message.Msg >= (int)WindowMessage.LBUTTONDOWN &&
                    e.Message.Msg <= (int)WindowMessage.MBUTTONDBLCLK)
            {
                HideToolTip();
            }
        }

        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.timerDisplayToolTip = new System.Windows.Forms.Timer(this.components);
            this.toolTip = new System.Windows.Forms.ToolTip(this.components);
            this.timerLeaveControl = new System.Windows.Forms.Timer(this.components);
            // 
            // timerDisplayToolTip
            // 
            this.timerDisplayToolTip.Interval = 1000;
            this.timerDisplayToolTip.Tick += new System.EventHandler(this.timer_Tick);
            // 
            // timerLeaveControl
            // 
            this.timerLeaveControl.Interval = 500;
            this.timerLeaveControl.Tick += new System.EventHandler(this.timerLeaveControl_Tick);

        }
        
        
        private ToolTip toolTip;
        /// <summary>
        /// Gets the tool tip control.
        /// </summary>
        /// <value>The tool tip control.</value>
        public ToolTip ToolTipControl
        {
            get { return toolTip; }
        }

        /// <summary>
        /// Gets or sets the target control.
        /// </summary>
        /// <value>The target control.</value>
        public Control TargetControl
        {
            get {return _sniffer.TargetControl; }
            set 
            { 
                _sniffer.TargetControl = value;

                if (value != null)
                {
                    Form form = _sniffer.TargetControl.FindForm();

                    if (form != null)
                    {
                        form.Move += new EventHandler(form_Move);
                    }
                }
            }
        }

        private void HideToolTip()
        {
            if (IsToolTipVisible)
            {
                toolTip.Hide(TargetControl);
                _displayStamp = DateTime.MinValue;
                timerLeaveControl.Stop();
            }
        }

        void form_Move(object sender, EventArgs e)
        {
            HideToolTip();
        }

        private string _toolTipText;
        /// <summary>
        /// Gets or sets the tool tip text.
        /// </summary>
        /// <value>The tool tip text.</value>
        public string ToolTipText
        {
            get { return this._toolTipText; }
            set { this._toolTipText = value; }
        }

        private int _displayDuration = 10000;
        /// <summary>
        /// Gets or sets the display duration.
        /// </summary>
        /// <value>The display duration.</value>
        public int DisplayDuration
        {
            get { return this._displayDuration; }
            set { this._displayDuration = value; }
        }

        /// <summary>
        /// Gets a value indicating whether the tooltip is visible.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if the tooltip is visible; otherwise, <c>false</c>.
        /// </value>
        public bool IsToolTipVisible
        {
            get
            {
                if (_displayStamp.AddMilliseconds((double)DisplayDuration) <= DateTime.Now)
                    return false;

                return true;
            }
        }

        private void timer_Tick(object sender, EventArgs e)
        {
            timerDisplayToolTip.Stop();

            if (TargetControl != null)
            {
                timerLeaveControl.Start();
                toolTip.Show(ToolTipText, TargetControl,
                             new Point(0, TargetControl.Height), DisplayDuration);
            }

            _displayStamp = DateTime.Now;
        }

        private void timerLeaveControl_Tick(object sender, EventArgs e)
        {
            if (TargetControl != null)
            {
                Point mousePos = TargetControl.PointToClient(Control.MousePosition);

                if (!TargetControl.ClientRectangle.Contains(mousePos))
                    HideToolTip();
            }
        }
    }
}
